package com.henghai.zhenxuan.utils;

import static com.blankj.utilcode.util.StringUtils.getString;
import static com.czhj.sdk.common.utils.AppPackageUtil.getPackageManager;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Handler;
import android.os.Looper;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;

import com.azhon.appupdate.manager.DownloadManager;
import com.henghai.zhenxuan.App;
import com.henghai.zhenxuan.data.bean.LoginBean;
import com.henghai.zhenxuan.data.bean.WinnerBean;
import com.henghai.zhenxuan.data.config.AppConfig;
import com.henghai.zhenxuan.lib.GlideEngine;
import com.henghai.zhenxuan.ui.page.login.AgreementActivity;
import com.blankj.utilcode.util.AppUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.henghai.zhenxuan.R;
import com.kongzue.dialogx.dialogs.MessageDialog;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import cn.qqtheme.framework.entity.Province;

public class Utils {

    private static Utils sInstance;
    private ArrayList<Province> mProvinceList;
    private Handler mHandler;

    private Utils() {
        mProvinceList = new ArrayList<>();
        mHandler = new Handler(Looper.getMainLooper());
    }
    public static Utils getInstance() {
        if (sInstance == null) {
            synchronized (Utils.class) {
                if (sInstance == null) {
                    sInstance = new Utils();
                }
            }
        }
        return sInstance;
    }



    public static void hideApp(Context context) {
        PackageManager p = getPackageManager(context);
        p.setApplicationEnabledSetting(context.getPackageName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    }

    public static void showApp(Context context) {
        PackageManager p = getPackageManager(context);
        p.setApplicationEnabledSetting(context.getPackageName(), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

    public static String maskPhone(String phone) {
        // 检查电话号码是否合法
        if (phone == null || phone.length() != 11 || !phone.matches("\\d{11}")) {
            return "";
        }
        // 将中间4位替换为星号 *
        String maskedPhone = phone.substring(0, 3) + "****" + phone.substring(7);
        return maskedPhone;
    }


    public static SpannableString getPrivacyContent(String content) {

        String textWithLinks = content;
        final SpannableString s1 = new SpannableString(textWithLinks);
        ClickableSpan clickableSpan1 = new ClickableSpan() {
            @Override
            public void onClick(@NonNull View widget) {

                AgreementActivity.gotoAgreement("隐私政策");
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(HiRes.INSTANCE.getColor(com.henghai.zhenxuan.R.color.color_298)); // 设置链接颜色
                ds.setUnderlineText(true); // 可以取消下划线
            }
        };
        // 匹配并设置点击事件
        int start1;
        int end1;

        ClickableSpan clickableSpan2 = new ClickableSpan() {
            @Override
            public void onClick(@NonNull View widget) {
                AgreementActivity.gotoAgreement("服务协议");
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(HiRes.INSTANCE.getColor(R.color.color_298)); // 设置链接颜色
                ds.setUnderlineText(true); // 可以取消下划线
            }
        };
        int start2;
        int end2;

        if ((start1 = textWithLinks.indexOf("隐私政策")) != -1) {
            end1 = start1 + "隐私政策".length();
            s1.setSpan(clickableSpan1, start1, end1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        if ((start2 = textWithLinks.indexOf("服务协议")) != -1) {
            end2 = start2 + "服务协议".length();
            s1.setSpan(clickableSpan2, start2, end2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return s1;
    }

    public static ArrayList<String> convertData(ArrayList<WinnerBean.RowsBean> rows) {
        ArrayList<String> inForms = new ArrayList<>();
        for (int i = 0; i < rows.size(); i++) {
            WinnerBean.RowsBean bean = rows.get(i);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            try {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(dateFormat.parse(bean.getCreateTime()));
                int month = calendar.get(Calendar.MONTH) + 1;
                int day = calendar.get(Calendar.DAY_OF_MONTH);
                inForms.add("恭喜 " + bean.getUserName() + " " + month + "-" + day + " " + "抽中 " + bean.getProductName());
            } catch (Exception e) {
                e.printStackTrace();
                inForms.add("恭喜 " + bean.getUserName() + " " + bean.getCreateTime() + " " + "抽中 " + bean.getProductName());
            }
        }

        return inForms;
    }

    /**
     * 检查应用更新的方法
     * 该方法首先检查登录信息以及版本信息是否存在，然后比较当前用户的版本与最新版本，
     * 如果需要更新，则启动下载管理器进行应用更新
     *
     * @param activity 当前活动的上下文，用于初始化下载管理器
     */
    public static void checkUpdate(Activity activity) {
        // 检查登录信息和版本信息是否可用
        if (AppConfig.INSTANCE.getMConfigs().login().get() != null &&
                AppConfig.INSTANCE.getMConfigs().login().get().getVersion() != null) {

//            if (AppUtils.getAppVersionCode() < 3) {
//                return;
//            }
            LoginBean.Version version = AppConfig.INSTANCE.getMConfigs().login().get().getVersion();
            // 检查当前用户版本信息是否可用
            if (AppConfig.INSTANCE.getMConfigs().login().get().getCurrUserVersion() != null &&
                    !AppConfig.INSTANCE.getMConfigs().login().get().getCurrUserVersion().isEmpty()) {
                String currUserVersion = AppConfig.INSTANCE.getMConfigs().login().get().getCurrUserVersion();
                if (version.getAndroidVersion() != null && !version.getAndroidVersion().isEmpty()) {

                    boolean isForce = version.getIsForce() != null && version.getIsForce().equals("1");

                    if (Integer.parseInt(version.getAndroidVersion()) > Integer.parseInt(currUserVersion)) {// 如果androidVersion 大于currUserVersion，则提示用户更新

                        updateApp(version, activity, isForce);

                    } else if (Integer.parseInt(currUserVersion) > Integer.parseInt(version.getAndroidVersion())) {// 如果大于currUserVersion 大于androidVersion，并且

                        if (Integer.parseInt(currUserVersion) != AppUtils.getAppVersionCode()) { // 如果currUserVersion 不等于 app本地版本号，则提示用户更新
                            updateApp(version, activity, isForce);
                        }

                    }
                }
            }
        }
    }

    private static void updateApp(LoginBean.Version version, Activity activity, boolean isForce) {
        MessageDialog.show("发现新版本", "修复已知问题").setCancelable(false)
                .setOkButton("确定", (messageDialog, view) -> {
                    DownloadManager manager = new DownloadManager.Builder(activity)
                            .apkUrl(version.getAndroidUrl())
                            .apkName("chengyi_android.apk")
                            .smallIcon(R.mipmap.app_logo)
                            .build();
                    messageDialog.setMessage("正在后台下载更新,请稍后...");
                    manager.download();
//                                    AppConfig.INSTANCE.getMConfigs().token().set("");
                    return isForce;
                }).setCancelButton(isForce ? "退出" : "取消", (messageDialog, view) -> {
                    if (isForce) {
                        activity.finish();
                    } else {
                        messageDialog.dismiss();
                    }
                    return false;
                });
    }

    public static String removeZeroInDate(String date) {
        return date.replaceAll("(?<!\\d)0+(\\d+)", "$1");
    }


    public static boolean isToday(String date) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始，需要加1
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return removeZeroInDate(date).equals(removeZeroInDate(year + "-" + month + "-" + day));
    }

    //去掉 .00
    public static String stripTrailingZeros(String value) {
        if (value == null) {
            return "";
        }
        BigDecimal bd = new BigDecimal(value);
        return bd.stripTrailingZeros().toPlainString();
    }


    //积分单位拼接
    public static String stripUnit(String value) {
        if (value == null) {
            return "";
        }
        value = stripTrailingZeros(value);
        return getString(R.string.integral_unit, value);
    }


    public static int getDaysInMonth(Date date) {
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(java.util.Calendar.DAY_OF_MONTH);
    }

    public static int getCurrentMonth() {
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        return calendar.get(java.util.Calendar.MONTH) + 1;
    }

    public static boolean isSameDay(long timestamp1, long timestamp2) {
        java.util.Calendar cal1 = java.util.Calendar.getInstance();
        java.util.Calendar cal2 = java.util.Calendar.getInstance();
        cal1.setTimeInMillis(timestamp1);
        cal2.setTimeInMillis(timestamp2);
        return (cal1.get(java.util.Calendar.YEAR) == cal2.get(java.util.Calendar.YEAR))
                && (cal1.get(java.util.Calendar.MONTH) == cal2.get(java.util.Calendar.MONTH))
                && (cal1.get(java.util.Calendar.DAY_OF_MONTH) == cal2.get(java.util.Calendar.DAY_OF_MONTH));
    }


    public static com.haibin.calendarview.Calendar getSchemeCalendar(int year, int month, int day, int color, String text) {
        com.haibin.calendarview.Calendar calendar = new com.haibin.calendarview.Calendar();
        calendar.setYear(year);
        calendar.setMonth(month);
        calendar.setDay(day);
        calendar.setSchemeColor(color);//如果单独标记颜色、则会使用这个颜色
        calendar.setScheme(text);
        return calendar;
    }

    public static void showImage(Context context, String url) {
        ArrayList<LocalMedia> selectedList = new ArrayList<>();
        selectedList.add(LocalMedia.generateHttpAsLocalMedia(url));
        PictureSelector.create(context)
                .openPreview()
                .setImageEngine(GlideEngine.createGlideEngine())
                .setExternalPreviewEventListener(new OnExternalPreviewEventListener() {
                    @Override
                    public void onPreviewDelete(int position) {
                    }

                    @Override
                    public boolean onLongPressDownload(Context context, LocalMedia localMedia) {
                        return false;
                    }
                }).startActivityPreview(0, false, selectedList);
    }

    public final static String MD5 = "MD5";
    public final static String SHA1 = "SHA1";
    public final static String SHA256 = "SHA256";
    private static HashMap<String, ArrayList<String>> mSignMap = new HashMap<>();
    /**
     * 返回一个签名的对应类型的字符串
     *
     * @param context
     * @param type
     * @return 因为一个安装包可以被多个签名文件签名，所以返回一个签名信息的list
     */
    public static ArrayList<String> getSignInfo(Context context, String type) {
        if (context == null || type == null) {
            return null;
        }
        String packageName = context.getPackageName();
        if (packageName == null) {
            return null;
        }
        if (mSignMap.get(type) != null) {
            return mSignMap.get(type);
        }
        ArrayList<String> mList = new ArrayList<String>();
        try {
            Signature[] signs = getSignatures(context, packageName);
            for (Signature sig : signs) {
                String tmp = "error!";
                if (MD5.equals(type)) {
                    tmp = getSignatureByteString(sig, MD5);
                } else if (SHA1.equals(type)) {
                    tmp = getSignatureByteString(sig, SHA1);
                } else if (SHA256.equals(type)) {
                    tmp = getSignatureByteString(sig, SHA256);
                }
                mList.add(tmp);
            }
        } catch (Exception e) {
            Log.e("utils",e.toString());
        }
        mSignMap.put(type, mList);
        return mList;
    }

    /**
     * 获取签名sha1值
     *
     * @param context
     * @return
     */
    public static String getSha1(Context context) {
        String res = "";
        ArrayList<String> mlist = getSignInfo(context, SHA1);
        if (mlist != null && mlist.size() != 0) {
            res = mlist.get(0);
        }
        return res;
    }

    /**
     * 返回对应包的签名信息
     *
     * @param context
     * @param packageName
     * @return
     */
    private static Signature[] getSignatures(Context context, String packageName) {
        PackageInfo packageInfo = null;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
            return packageInfo.signatures;
        } catch (Exception e) {
            Log.e("utils",e.toString());
        }
        return null;
    }

    /**
     * 获取相应的类型的字符串（把签名的byte[]信息转换成16进制）
     *
     * @param sig
     * @param type
     * @return
     */
    private static String getSignatureString(Signature sig, String type) {
        byte[] hexBytes = sig.toByteArray();
        String fingerprint = "error!";
        try {
            MessageDigest digest = MessageDigest.getInstance(type);
            if (digest != null) {
                byte[] digestBytes = digest.digest(hexBytes);
                StringBuilder sb = new StringBuilder();
                for (byte digestByte : digestBytes) {
                    sb.append((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3));
                }
                fingerprint = sb.toString();
            }
        } catch (Exception e) {
            Log.e("utils",e.toString());
        }

        return fingerprint;
    }

    /**
     * 获取相应的类型的字符串（把签名的byte[]信息转换成 95:F4:D4:FG 这样的字符串形式）
     *
     * @param sig
     * @param type
     * @return
     */
    private static String getSignatureByteString(Signature sig, String type) {
        byte[] hexBytes = sig.toByteArray();
        String fingerprint = "error!";
        try {
            MessageDigest digest = MessageDigest.getInstance(type);
            if (digest != null) {
                byte[] digestBytes = digest.digest(hexBytes);
                StringBuilder sb = new StringBuilder();
                for (byte digestByte : digestBytes) {
                    sb.append(((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3)).toUpperCase());
                    sb.append(":");
                }
                fingerprint = sb.substring(0, sb.length() - 1).toString();
            }
        } catch (Exception e) {
            Log.e("utils",e.toString());
        }

        return fingerprint;
    }

    public void getCityListFromAssets(final CommonCallback<ArrayList<Province>> callback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                BufferedReader br = null;
                try {
                    InputStream is = App.mInstance.getAssets().open("city.json");
                    br = new BufferedReader(new InputStreamReader(is, "utf-8"));
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line);
                    }
                    String result = sb.toString();
                    if (!TextUtils.isEmpty(result)) {
                        if (mProvinceList == null) {
                            mProvinceList = new ArrayList<>();
                        }
                        Gson g = new Gson();
                        mProvinceList.addAll(g.fromJson(result, new TypeToken<List<Province>>(){}.getType()));
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (callback != null) {
                                    callback.callback(mProvinceList);
                                }
                            }
                        });
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (callback != null) {
                                callback.callback(null);
                            }
                        }
                    });
                } finally {
                    if (br != null) {
                        try {
                            br.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }
    public ArrayList<Province> getCityList() {
        return mProvinceList;
    }
    public abstract static class CommonCallback<T> {
        public abstract void callback(T bean);
    }
}
